package com.newy.service.sys;

import java.lang.management.ClassLoadingMXBean;
import java.lang.management.CompilationMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.util.Date;

import org.springframework.stereotype.Service;

import com.newy.core.BaseService;
import com.newy.domain.sys.vo.ServerJvmDesc;
import com.newy.domain.sys.vo.ServerOsDesc;
import com.newy.domain.sys.vo.ServerPerf;
import com.sun.management.OperatingSystemMXBean;

/**
 * 服务器监控类，展示服务器jvm、os的一些基本信息和性能信息
 * @author linzongxue
 * @create_date 2011-12-21
 */
@Service
public class MonitorService  extends BaseService{
	/**
	 * 获取服务器操作系统的一些描述信息
	 */
	public ServerOsDesc getServerOsDesc(){
		ServerOsDesc osDesc = new ServerOsDesc();
		OperatingSystemMXBean osBean = (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
		osDesc.setName(osBean.getName());
		osDesc.setArch(osBean.getArch());
		osDesc.setVersion(osBean.getVersion());
		osDesc.setProcessorCount(osBean.getAvailableProcessors());
		osDesc.setTotalPhysicalMem(osBean.getTotalPhysicalMemorySize());
		return osDesc;
	}

	/**
	 * 获取服务器操Java虚拟机的一些描述信息
	 */
	public ServerJvmDesc getServerJvmDesc(){
		ServerJvmDesc jvmDesc = new ServerJvmDesc();
		CompilationMXBean cplBean = ManagementFactory.getCompilationMXBean();
		RuntimeMXBean rtBean = ManagementFactory.getRuntimeMXBean();
		
		jvmDesc.setJreVersion(System.getProperty("java.version"));
		jvmDesc.setJitCompiler(cplBean.getName());
		jvmDesc.setName(rtBean.getVmName());
		jvmDesc.setVendor(rtBean.getVmVendor());
		jvmDesc.setVersion(rtBean.getVmVersion());
		jvmDesc.setRuntimeName(rtBean.getName());
		jvmDesc.setStartTime(rtBean.getStartTime());
		return jvmDesc;
	}

	/**
	 * 获取服务器的一些性能数据，包括Java虚拟机和操作系统
	 */
	public ServerPerf getServerPerfData(){
		ServerPerf perf = new ServerPerf();		
		//堆内存
		MemoryUsage heapMemUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
		perf.setHeapMemInit(heapMemUsage.getInit());
		perf.setHeapMemCommitted(heapMemUsage.getCommitted());
		perf.setHeapMemUsed(heapMemUsage.getUsed());
		perf.setHeapMemMax(heapMemUsage.getMax());
		//栈内存
		MemoryUsage nonHeapMemUsage = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
		perf.setNonHeapMemMax(nonHeapMemUsage.getMax());
		perf.setNonHeapMemUsed(nonHeapMemUsage.getUsed());
		
		//线程
		ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
		perf.setLiveThreadCount(threadBean.getThreadCount());
		perf.setPeakThreadCount(threadBean.getPeakThreadCount());
		perf.setTotalThreadCount(threadBean.getTotalStartedThreadCount());
		//类
		ClassLoadingMXBean classBean = ManagementFactory.getClassLoadingMXBean();
		perf.setLoadedClassCount(classBean.getLoadedClassCount());
		perf.setUnoadedClassCount(classBean.getUnloadedClassCount());
		perf.setTotalLoadedClassCount(classBean.getTotalLoadedClassCount());
		
		//操作系统
		OperatingSystemMXBean osBean = (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
		perf.setOsLoadAverage(osBean.getSystemLoadAverage()); //系统CPU使用率
		perf.setOsTotalPhysicalMem(osBean.getTotalPhysicalMemorySize());
		perf.setOsFreePhysicalMem(osBean.getFreePhysicalMemorySize());
		perf.setOsTotalSwapSpace(osBean.getTotalSwapSpaceSize());
		perf.setOsFreeSwapSpace(osBean.getFreeSwapSpaceSize());
		
		//其它
		RuntimeMXBean rtBean = ManagementFactory.getRuntimeMXBean();
		perf.setJvmUptime(rtBean.getUptime()); //jvm正经运行时间
		perf.setJvmCpuTime(osBean.getProcessCpuTime()); //处理cpu时间
		perf.setJvmCpuUsage(this.getJvmCpuUsage());//jvm对cpu的占用率
		
		perf.setTime(new Date()); //获取数据的时间
		
		return perf;
	}
	
	/**
	 * 计算jvm占用cpu使用率
	 */
	private synchronized double getJvmCpuUsage(){
		if ( lastSystemTime == 0 ){
			lastSystemTime = System.nanoTime();
            return 0;
        }

        long systemTime = System.nanoTime();
        long processCpuTime = 0;

        OperatingSystemMXBean osBean = (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
        processCpuTime = osBean.getProcessCpuTime();

        double cpuUsage = (double)( processCpuTime - lastProcessCpuTime ) / ( systemTime - lastSystemTime );
        if (cpuUsage > 1){ //算得不准确，废弃
        	cpuUsage = 0;
        }
        lastSystemTime     = systemTime;
        lastProcessCpuTime = processCpuTime;

        return cpuUsage / osBean.getAvailableProcessors();
	}

	private long lastSystemTime      = 0;
    private long lastProcessCpuTime  = 0;
}
